//扩展字符串功能
if(!String.prototype.endsWith) {
	/**
	 * 判断是否以某个字符串开头
	 * @param searchString 字符串
	 * @param position 以第几个字符作为字符串的结尾，默认以字符串的最后一个字符作为结尾字符
	 */
    String.prototype.endsWith = function(searchString, position) {
        var subjectString = this.toString();
        if(position === undefined || position > subjectString.length) {
            position = subjectString.length;
        }
        position -= searchString.length;
        var lastIndex = subjectString.indexOf(searchString, position);
        return lastIndex !== -1 && lastIndex === position;
    };
};
if(!String.prototype.startsWith) {
	/**
	 * 判断是否以某个字符串开头
	 * @param searchString 字符串
	 * @param position 以第几个字符作为字符串的开头，默认以第0个字符开头，
	 * 	<p>如abcd，若position=1，那么"abcd".startsWith("bcd")的返回
	 * 	值为true，而"abcd".startsWith("abcd")的返回值为false</p>
	 */
    String.prototype.startsWith = function(searchString, position) {
        position = position || 0;
        return this.lastIndexOf(searchString, position) === position;
    };
};
if(!String.prototype.contains) {
	/**
	 * 判断是否包含某个字符串
	 */
    String.prototype.contains = function(str) {
    	if (StringUtil.isEmpty(this)) {
			return false;
		}
		return this.indexOf(str) >= 0;
    };
};
/**
 * 删除字符串左右两端的空格
 */
if(!String.prototype.trim) {
	String.prototype.trim=function(){
		return this.replace(/(^\s*)|(\s*$)/g, '');
	};
}
/**
 * 对Date的扩展，将 Date 转化为指定格式的String *
 * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q) 可以用 1-2 个占位符 * 年(y)可以用 1-4
 * 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字) * eg: * (new Date()).pattern("yyyy-MM-dd
 * hh:mm:ss.S")==> 2006-07-02 08:09:04.423 (new Date()).pattern("yyyy-MM-dd E
 * HH:mm:ss") ==> 2009-03-10 二 20:09:04 (new Date()).pattern("yyyy-MM-dd EE
 * hh:mm:ss") ==> 2009-03-10 周二 08:09:04 (new Date()).pattern("yyyy-MM-dd EEE
 * hh:mm:ss") ==> 2009-03-10 星期二 08:09:04 (new Date()).pattern("yyyy-M-d
 * h:m:s.S") ==> 2006-7-2 8:9:4.18
 */
if (!Date.prototype.pattern) {
	Date.prototype.pattern = function(fmt) {
    	var o = {
    		"M+" : this.getMonth() + 1,
    		// 月份
    		"d+" : this.getDate(),
    		// 日
    		"h+" : this.getHours() % 12 == 0 ? 12 : this.getHours() % 12,
    		// 小时
    		"H+" : this.getHours(),
    		// 小时
    		"m+" : this.getMinutes(),
    		// 分
    		"s+" : this.getSeconds(),
    		// 秒
    		"q+" : Math.floor((this.getMonth() + 3) / 3),
    		// 季度
    		"S" : this.getMilliseconds()
    	// 毫秒
    	};
    	var week = {
    		"0" : "/u65e5",
    		"1" : "/u4e00",
    		"2" : "/u4e8c",
    		"3" : "/u4e09",
    		"4" : "/u56db",
    		"5" : "/u4e94",
    		"6" : "/u516d"
    	};
    	if (/(y+)/.test(fmt)) {
    		fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    	}
    	if (/(E+)/.test(fmt)) {
    		fmt = fmt.replace(RegExp.$1,((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f": "/u5468"): "")
    								+ week[this.getDay() + ""]);
    	}
    	for ( var k in o) {
    		if (new RegExp("(" + k + ")").test(fmt)) {
    			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]): (("00" + o[k]).substr(("" + o[k]).length)));
    		}
    	}
    	return fmt;
    };
}
/**
 * 求取一个object对象的节点个数
 */
if (!Object.keys) {
	Object.keys = function(o) {
	    if (o !== Object(o)) {
	    	throw new TypeError('Object.keys called on a non-object');
	    }
	    var k = [], p = null;
	    for (p in o) {
	    	if (Object.prototype.hasOwnProperty.call(o, p)) {
	    		k.push(p);
	    	}
	    	return k;
	    }
	};
}
/**
 * 字符串工具
 */
if(!StringUtil){
	var StringUtil = {};
}
/**
 * 判空
 */
if(!StringUtil.isEmpty){
	StringUtil.isEmpty = function(str){
		return str == undefined || str.length == 0;
	};
}
/**
 * 判断是否非空
 */
if (!StringUtil.isNotEmpty) {
	StringUtil.isNotEmpty = function(str){
		return !StringUtil.isEmpty(str);
	};
}
/**
 * 是否为空白的，trim后为空串
 */
if(!StringUtil.isBlank){
	StringUtil.isBlank = function(str){
		return str == undefined || str.length == 0 || str.trim().length == 0;
	};
}
/**
 * 判断是否不为空白的，trim后为空串
 */
if(!StringUtil.isNotBlank){
	StringUtil.isNotBlank = function(str){
		return !StringUtil.isBlank(str);
	};
}
/**
 * 判断是否为字符串
 */
if(!StringUtil.isString){
	StringUtil.isString = function(str){
		return typeof str=="string";
	};
}
/**
 * 字符串长度是否小于或等于某个数
 */
if (!StringUtil.lengthLessThan) {
	StringUtil.lengthLessThan = function(str, len){
		return !StringUtil.isBlank(str) && str.length <= len;
	};
}
/**
 * 字符串长度是否大于某个数
 */
if (!StringUtil.lengthGreaterThan) {
	StringUtil.lengthGreaterThan = function(str, len){
		return !StringUtil.isBlank(str) && str.length > len;
	};
}
/**
 * 数值格式化
 * @日期 2017-06-01 
 * @示例：
 * <p>var cash = StringUtil.formatNumberWithCash(1141185214); // cash = "1,141,185,214"</p>
 */
if (!StringUtil.formatNumberWithCash) {
	StringUtil.formatNumberWithCash = function(num) {
		if (ObjectUtil.isInteger(num)) {
			var cash = num.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
			return cash;
		}
	};
}
/**
 * 判断两个字符串是否相等
 * @日期 2017-08-06 
 */
if (!StringUtil.equals) {
	StringUtil.equals = function(str1, str2) {
		if (str1 != null && str2 != null) {
			return str1 == str2;
		}
		return false;
	};
}
/**
 * 对象工具
 */
if(!ObjectUtil){
	var ObjectUtil = {};
}
/**
 * 判断是否为函数对象
 */
if (!ObjectUtil.isFunction) {
	ObjectUtil.isFunction = function(func) {
		if ( func && func instanceof Function ) {
			return true;
		}
		return false;
	};
}
/**
 * 判断是否为函数对象
 */
if (!ObjectUtil.isArray) {
	ObjectUtil.isArray = function(arr) {
		if ( arr && arr instanceof Array ) {
			return true;
		}
		return false;
	};
}
/**
 * 判断是否为一个简单的对象
 */
if (!ObjectUtil.isSimpleObject) {
	ObjectUtil.isSimpleObject = function(obj) {
		if (obj == null || obj == undefined) {
			return false;
		}
		if (typeof obj == 'object') {
			if (obj instanceof Array) {
				return false;
			}
			return true;
		}
		return false;
	};
}
/**
 * 判断是否为整数
 */
if (!ObjectUtil.isInteger) {
	ObjectUtil.isInteger = function(num) {
		if ( num != undefined) {
			var numStr = new String(num).toString();
			var reg = new RegExp("^-?\\d+$");
			return reg.test(numStr);
		}
		return false;
	};
}
/**
 * 判断是否为boolean类型，若字符串为true/false，也表示为Boolean类型
 */
if (!ObjectUtil.isBoolean) {
	ObjectUtil.isBoolean = function(obj) {
		if (typeof obj == "boolean") {
			return true;
		}
		if (typeof obj == "string") {
			var s = obj.toLowerCase();
			return s == "true" || s == "false";
		}
		return false;
	};
}
/**
 * 清理options对象
 * 1.删除options对象中值为空串的键值对
 * 2.实例化funcNames函数名称数组为对应的函数对象
 * @param options object对象
 * @param funcNames 函数名称数组
 */
if (!ObjectUtil.cleanup) {
	ObjectUtil.cleanup = function(options, funcNames) {
		for (var item in options) {
			if (StringUtil.isString(options[item]) && StringUtil.isBlank(options[item])) {
				delete options[item];
			}
			if (ObjectUtil.isBoolean(options[item])) {
				options[item] = ( options[item] == 'true' || options[item] == true);
			}
		}
		if (ObjectUtil.isArray(funcNames) && ArrayUtil.hasData(funcNames)) {
			for (item in funcNames) {
				var name = funcNames[item];
				var obj = eval(options[name]);
				options[name] = obj;
			}
		}
	};
}
/**
 * 数组工具
 */
if(!ArrayUtil){
	var ArrayUtil = {};
}
/**
 * 判断是否为函数对象
 */
if (!ArrayUtil.isArray) {
	ArrayUtil.isArray = function(arr) {
		if ( arr && arr instanceof Array ) {
			return true;
		}
		return false;
	};
}
/**
 * 判断是否包含数据
 */
if (!ArrayUtil.hasData) {
	ArrayUtil.hasData = function(arr) {
		if ( ArrayUtil.isArray(arr) && arr.length > 0 ) {
			return true;
		}
		return false;
	};
}
/**
 * 给对象数组的某一列赋固定值
 */
if (!ArrayUtil.setPropertyValue) {
	ArrayUtil.setPropertyValue = function(arr, property, value) {
		if (!ArrayUtil.hasData(arr)) {
			return ;
		}
		for (var i = 0 ; i < arr.length; i++) {
			var item = arr[i];
			item[property] = value;
		}
	};
}
/**
 * 排序规则
 */
if (!ArrayUtil.by) {
	ArrayUtil.by = function(key,asc) {
		return function compareFunc(a, b) {
			var param1=null;
			var param2=null;
			if(asc){
				param1=a[key];	param2=b[key];
			} else{
				param2=a[key];	param1=b[key];
			}
		    //如果两个参数均为字符串类型
		    if (typeof param1 == "string" && typeof param2 == "string") {
		        return param1.localeCompare(param2);
		    }
		    //如果参数1为数字，参数2为字符串
		    if (typeof param1 == "number" && typeof param2 == "string") {
		        return -1;
		    }
		    //如果参数1为字符串，参数2为数字
		    if (typeof param1 == "string" && typeof param2 == "number") {
		        return 1;
		    }
		    //如果两个参数均为数字
		    if (typeof param1 == "number" && typeof param2 == "number") {
		        if (param1 > param2) return 1;
		        if (param1 == param2) return 0;
		        if (param1 < param2) return -1;
		    }
		};
	};
}
if (!ArrayUtil.max) {
	ArrayUtil.max = function(arr) {
		if (!ArrayUtil.hasData(arr)) {
			return null;
		}
		var max = Number.MIN_VALUE;
		for (var i = 0; i < arr.length; i ++ ) {
			if (arr[i] > max) {
				max = arr[i];
			}
		}
		return max;
	};
}
/**
 * 函数队列工具，常用于扩展到具体的对象中去
 * 举例：
 * ajax是一个对象，它有一个回调函数onSuccess，在ajax请求成功之后调用，现在希望在执行回
 * 调函数onSuccess之前执行一个或多个函数，但不希望改变原有的代码，那么就可以让ajax
 * 扩展FunctionEmbedUtil对象，然后调用embedFunction即可
 * $.extend(ajax, FunctionEmbedUtil);
 * ajax.embedFunction('onSuccess', function(data, xhr, status){
 *     console.log('正在执行被植入的函数');
 * }, ajax);
 * 需要注意的是，我们需要在ajax的onSuccess函数之前调用executeEmbedFunctions
 * this.executeEmbedFunctions(function(item){
 *     item && item(data, xhr, status);
 * }, 'onSuccess', this);
 */
if (!FunctionEmbedUtil) {
	var FunctionEmbedUtil = {};
}
// 向对象中植入函数
if (!FunctionEmbedUtil.embedFunction) {
	FunctionEmbedUtil.embedFunction = function(funcName, func, that) {
		if (!that.functionQueueSet) {
			that.functionQueueSet = {};
		}
		if (!that.functionQueueSet[funcName]) {
			that.functionQueueSet[funcName] = [];
		}
		that.functionQueueSet[funcName].push(func);
	};
}
// 执行植入的函数
if (!FunctionEmbedUtil.executeEmbedFunctions) {
	FunctionEmbedUtil.executeEmbedFunctions = function(func, funcName, that) {
		if (!that.functionQueueSet) {
			that.functionQueueSet = {};
		} 
		if (ArrayUtil.hasData(that.functionQueueSet[funcName])){
			$.each(that.functionQueueSet[funcName],function(index, item) {
				func(item);
			});
		}
	};
}
/**
 * 工具
 */
if (!Util) {
	var Util = {};
}
/**
 * HTML转码
 * @param 存在html代码的文本
 * @returns 转码后的字符串
 */
if (!Util.htmlEncode) {
	Util.htmlEncode=function(html){
		var temp = document.createElement ("div");
		(temp.textContent != null) ? (temp.textContent = html) : (temp.innerText = html);
		var output = temp.innerHTML;
		temp = null;
		return output;
	};
}
/**
 * HTML解码
 * @param 将文本解码成html代码
 * @returns 解码后的字符串
 */
if (!Util.htmlDecode) {
	Util.htmlDecode=function(text){
		var temp = document.createElement("div");   
		temp.innerHTML = text;   
		var output = temp.innerText || temp.textContent;   
		temp = null;   
		return output;
	};
}
/**
 * 验证工具 
 **/
if(!ValidateUtil){
	var ValidateUtil = {
			reg:{
				regEmail:new RegExp("^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$"),
				// regIdCard:new RegExp("^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X|x)$"),
				regPhoneNumber:new RegExp("^1(3[0-9]|4[57]|5[0-35-9]|8[0-9]|7[0,1,3,6,7,8])\\d{8}$"),
				regUrl:new RegExp("^(http|https|ftp)\\://([a-zA-Z0-9\\.\\-]+(\\:[a-zA-Z0-9\\.&amp;%\\$\\-]+)*@)?"
						+ "((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4]"
						+ "[0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}"
						+ "[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]"
						+ "{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+\\.[a-zA-Z]{2,4})(\\:[0-9]"
						+ "+)?(/[^/][a-zA-Z0-9\\.\\,\\?\\'\\/\\+&amp;%\\$#\\=~_\\-@]*)*$"),
				regDateYMDHMS:new RegExp("^(((20[0-3][0-9]-(0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|(20[0-3][0-9]-"
						+ "(0[2469]|11)-(0[1-9]|[12][0-9]|30))) (20|21|22|23|[0-1][0-9]):[0-5][0-9]:[0-5][0-9])$"),
				regChineseName:new RegExp("[\u4E00-\u9FA5,a-zA-z]{2,20}(?:·[\u4E00-\u9FA5,a-zA-z]{2,20})*")
			}
	};
}
if(!ValidateUtil.isEmail){
	ValidateUtil.isEmail = function(email){
		return ValidateUtil.reg.regEmail.test(email);
	};
}
if(!ValidateUtil.isIdCard){
	ValidateUtil.isIdCard = function(code){
		var city={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",
				      36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南", 50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",
				      61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外 "};
        // var tip = "";
        var pass= true;
        if(!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)){
            tip = "身份证号格式错误";
            pass = false;
        } else if(!city[code.substr(0,2)]){
            tip = "地址编码错误";
            pass = false;
        } else{
            //18位身份证需要验证最后一位校验位
            if(code.length == 18){
                code = code.split('');
                //∑(ai×Wi)(mod 11)
                //加权因子
                var factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ];
                //校验位
                var parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ];
                var sum = 0;
                var ai = 0;
                var wi = 0;
                for (var i = 0; i < 17; i++)
                {
                    ai = code[i];
                    wi = factor[i];
                    sum += ai * wi;
                }
                // var last = parity[sum % 11];
                if(parity[sum % 11] != code[17]){
                    tip = "校验位错误";
                    pass =false;
                }
            }
        }
        // if(!pass) alert(tip);
        return pass;
	};
}
if(!ValidateUtil.isPhoneNumber){
	ValidateUtil.isPhoneNumber = function(phoneNumber){
		return ValidateUtil.reg.regPhoneNumber.test(phoneNumber);
	};
}
if(!ValidateUtil.isUrl){
	ValidateUtil.isUrl = function(url){
		return ValidateUtil.reg.regUrl.test(url);
	};
}
if(!ValidateUtil.isDatetime){
	ValidateUtil.isDatetime = function(date, pattern){
		if (pattern == "yyyy-MM-dd HH:mm:ss" || pattern == "yyyy-MM-dd HH:ii:ss" ) {
			return ValidateUtil.reg.regDateYMDHMS.test(date);
		}
		return false;
	};
}
if (!ValidateUtil.validate) {
	ValidateUtil.validate = function(text, regs) {
		var reg = new RegExp(regs);
		var rs = reg.test(text);
		return rs;
	};
}
if (!ValidateUtil.isChineseName) {
	ValidateUtil.isChineseName = function(name) {
		return ValidateUtil.reg.regChineseName.test(name);
	};
}
/**
 * 文件名工具类
 * @日期：2017-3-24 18:15:01
 * @作者:lj
 */
if(FilenameUtils==undefined){
	var FilenameUtils={};
}
if(!FilenameUtils.indexOfLastSeparator){
	FilenameUtils.indexOfLastSeparator = function(filename){
		if (filename == null) {
			return -1;
		} else {
			var lastUnixPos = filename.lastIndexOf('/');
			var lastWindowsPos = filename.lastIndexOf('\\');
			return Math.max(lastUnixPos, lastWindowsPos);
		}
	};
}
if(!FilenameUtils.indexOfExtension){
	FilenameUtils.indexOfExtension = function(filename){
		if (filename == null) {
			return -1;
		} else {
			var extensionPos = filename.lastIndexOf('.');
			var lastSeparator = this.indexOfLastSeparator(filename);
			return lastSeparator <= extensionPos ? extensionPos : -1;
		};
	};
}
/**
 * @描述：获取文件名的扩展名
 * @日期：2017-3-24 18:15:01
 * @作者:lj
 */
if(!FilenameUtils.getExtension){
	FilenameUtils.getExtension = function(filename){
		if (filename == null)
			return null;
		var index = this.indexOfExtension(filename);
		if (index == -1)
			return "";
		else
			return filename.substring(index + 1);
	};
}
/**
 * @描述：获取文件名
 * @日期：2017-3-28 12:22:01
 * @作者:lj
 */
if(!FilenameUtils.getName){
	FilenameUtils.getName = function(filename){
		if (filename == null) {
			return null;
		} else {
			var index = this.indexOfLastSeparator(filename);
			return filename.substring(index + 1);
		}
	};
}
/**
 * @描述：删除文件名的扩展名
 * @日期：2017-3-28 12:22:01
 * @作者:lj
 */
if(!FilenameUtils.removeExtension){
	FilenameUtils.removeExtension = function(filename){
		if (filename == null)
			return null;
		var index = this.indexOfExtension(filename);
		if (index == -1)
			return filename;
		else
			return filename.substring(0, index);
	};
}
/**
 * @描述：获取文件名，没有扩展名
 * @日期：2017-3-28 12:22:01
 * @作者:lj
 */
if(!FilenameUtils.getBaseName){
	FilenameUtils.getBaseName = function(filename){
		return this.removeExtension(this.getName(filename));
	};
}
/**
 * @功能：普通类型的集合，针对字符串，整型等基础数据类型
 * @作者：lj
 * @日期：2017-05-21 
 */
if (!GenericSet) {
    function GenericSet(arr){
    	this.arr=arr;
    	if(this.arr==undefined)
    		this.arr=new Array();
    }
}
/**
 * 添加数据
 * @param data 要添加的数据
 */
if (!GenericSet.prototype.put) {
    GenericSet.prototype.put=function(data){
    	var _this=this;
    	$.each(this.arr,function(index,item){
    		if(data==item){
    			_this.arr.splice(index,1); // 若存在，删除掉
    		}
    	});
    	this.arr.push(data);
    };
}

/**
 * 根据主键添加数据
 * @param data 要添加的数据
 * @param key 对象的哪个属性作为主键
 */
if (!GenericSet.prototype.putByKey) {
	GenericSet.prototype.putByKey=function(data, key){
		var _this=this;
		$.each(this.arr,function(index,item){
			if (item == undefined) {
				return ;
			} 
			if (data[key] == item[key]) {
				_this.arr.splice(index,1); // 若存在，删除掉
			}
		});
		this.arr.push(data);
	};
}
/**
 * 根据数组的item，删除数据
 * @param data 要删除的数据
 * @param correct 删除数据后矫正，去除数组中的空值
 */
if (!GenericSet.prototype.remove) {
    GenericSet.prototype.remove=function(data,correct){
    	var _this = this;
    	$.each(this.arr,function(index,item){
    		if(data==item){
    			_this.arr.splice(index,1);
    		}
    	});
    	if(correct){
    		$.each(this.arr,function(index,item){
    			if(item>data){
    				_this.arr[index]=item-1;
    			}
    		});
    	}
    };
}
/**
 * 根据主键删除数据
 * @param data 要删除的数据
 * @param key 以对象的哪个属性作为主键
 */
if (!GenericSet.prototype.removeByKey) {
	GenericSet.prototype.removeByKey = function(data, key) {
		var _this = this;
		$.each(this.arr,function(index,item){
			if (item == undefined) {
				return ;
			} 
			if (item[key] == data[key]){
				_this.arr.splice(index,1);
			}
		});
	};
}
/**
 * 判断是否拥有某一项数据
 * @param 待判断的数据
 * @returns {Boolean}
 */
if (!GenericSet.prototype.hasItem) {
	GenericSet.prototype.hasItem = function(data) {
		var has = false;
		$.each(this.arr,function(index,item){
			if (item == undefined) {
				return ;
			} 
			if (item == data){
				has = true;
			}
		});
		return has;
		
	};
}
/**
 * 判断是否拥有某一项数据，以key作为主键
 * @param data 待判断的数据
 * @param key 主键
 * @returns {Boolean}
 */
if (!GenericSet.prototype.hasItemOfKey) {
	GenericSet.prototype.hasItemOfKey = function(data, key) {
		var has = false;
		$.each(this.arr,function(index,item){
			if (item == undefined) {
				return ;
			} 
			if (item[key] == data[key]){
				has = true;
			}
		});
		return has;
	};
}
/**
 * 获取长度
 * @returns {Integer}
 */
if (!GenericSet.prototype.size) {
    GenericSet.prototype.size=function(){
    	return this.arr.length;
    };
}
/**
 * 判断是否还拥有数据
 * @returns {Boolean}
 */
if (!GenericSet.prototype.hasData) {
	GenericSet.prototype.hasData=function(){
		return this.arr.length > 0;
	};
}
/**
 * 根据下标获取数据项
 * @returns {Object}
 */
if (!GenericSet.prototype.getByIndex) {
    GenericSet.prototype.getByIndex=function(index){
    	return this.arr[index];
    };
}
/**
 * 根据对象数组中，对象的key和value取对象
 * @param key 主键
 * @param value 主键的值
 */
if (!GenericSet.prototype.getItemByKey) {
	GenericSet.prototype.getItemByKey=function(key, value){
		var obj = null;
		$.each(this.arr,function(index,item){
			if (item == undefined) {
				return ;
			} 
			if(value == item[key]){
				obj = item;
			}
		});
		return obj;
	};
}
/**
 * @功能：获取最近传入的数据
 * @returns {Object}
 */
if (!GenericSet.prototype.latest) {
    GenericSet.prototype.latest=function(){
    	if(this.arr.length<=0)
    		throw new Error("GenericSet instance is empty");
    	return this.arr[this.arr.length-1];
    };
}
/**
 * 获取除arr中包含的所有
 * @示例：
 * 设定：GenericSet实例中的arr: 
 *       gset.arr = [2,0,1,3];
 *       arr = [0,3];
 * 那么：
 *       var rsarr = gset.except(arr);
 *       // rsarr = [2,1];
 * @param arr
 * @returns {Array}
 */
if (!GenericSet.prototype.except) {
    GenericSet.prototype.except = function(arr) {
    	var resultArr = new Array();
    	$.extend(resultArr, this.arr);
    	$.each(arr,function(index,item){
    		var mIndex = $.inArray(item,resultArr);
    		if (mIndex >= 0) {
    			resultArr.splice(mIndex, 1);
    		}
    	});
    	return resultArr;
    };
}
/**
 * @功能：判断数据是否存在于GenericSet.arr对象中
 * @param data
 * @returns {Boolean}
 */
if (!GenericSet.prototype.exist) {
    GenericSet.prototype.exist=function(data){
    	var exist = false;
    	$.each(this.arr,function(index,item){
    		if(data==item){
    			exist=true;
    		}
    	});
    	return exist;
    };
}
/**
 * 以主键判断数据是否存在于GenericSet.arr对象中
 * @param data 待判断数据
 * @param key 主键
 * @returns {Boolean}
 */
if (!GenericSet.prototype.existByKey) {
	GenericSet.prototype.existByKey=function(data,key){
		var exist = false;
		$.each(this.arr,function(index,item){
			if (item == undefined) {
				return ;
			} 
			if(data[key]==item[key]){
				exist=true;
			}
		});
		return exist;
	};
}
/**
 * @功能：清空
 */
if (!GenericSet.prototype.clear) {
    GenericSet.prototype.clear=function(){
    	this.arr=new Array();
    };
}
/**
 * @功能：判断arr中的数据是否都在GenericSet.arr中
 */
if (!GenericSet.prototype.containsAll) {
	GenericSet.prototype.containsAll=function(arr){
		for(var i = 0 ; i < arr.length; i++ ) {
			if (!this.exist(arr[i])) {
				return false;
			}
		}
		return true;
	};
}
/**
 * @功能：判断arr中的数据是否都在GenericSet.arr中，依据对象的key属性值判断
 */
if (!GenericSet.prototype.containsAllOfKey) {
	GenericSet.prototype.containsAllOfKey=function(arr, key){
		for(var i = 0 ; i < arr.length; i++ ) {
			if (!this.existByKey(arr[i][key])) {
				return false;
			}
		}
		return true;
	};
}
/**
 * 合并GenericSet
 * @param gset
 */
if (!GenericSet.prototype.merge) {
	GenericSet.prototype.merge = function(gset) {
		if (gset.arr.length <= 0) {
			return this;
		}
		for (var i = 0; i < gset.arr.length; i++ ){
			var item = gset.arr[i];
			this.put(item);
		}
		return this;
	};
}
/**
 * 合并GenericSet，依据对象的key属性判断
 * @param gset
 */
if (!GenericSet.prototype.mergeOfKey) {
	GenericSet.prototype.mergeOfKey = function(gset, key) {
		if (gset.arr.length <= 0) {
			return this;
		}
		for (var i = 0; i < gset.arr.length; i++ ){
			var item = gset.arr[i];
			this.putByKey(item);
		}
		return this;
	};
}
/**
 * @功能：记录器
 * @作者：lj
 */
if (!Recorder) {
	function Recorder() {
		this.updateRecords = new GenericSet();
		this.newRecords = new GenericSet();
		this.deleteRecords = new GenericSet();
	}
}
/**
 * 获取更新的记录
 */
if (!Recorder.prototype.getUpdateRecords) {
	Recorder.prototype.getUpdateRecords = function() {
		return this.updateRecords;
	};
}
/**
 * 获取新增的记录
 */
if (!Recorder.prototype.getNewRecords) {
	Recorder.prototype.getNewRecords = function() {
		return this.newRecords;
	};
}
/**
 * 获取删除的记录
 */
if (!Recorder.prototype.getDeleteRecords) {
	Recorder.prototype.getDeleteRecords = function() {
		return this.deleteRecords;
	};
}
/**
 * 清除所有记录
 */
if (!Recorder.prototype.clearAll) {
	Recorder.prototype.clearAll = function() {
		this.updateRecords.arr = [];
		this.newRecords.arr = [];
		this.deleteRecords.arr = [];
	};
}
/**
 * 判断是否存在用户操作
 */
if (!Recorder.prototype.hasOperate) {
	Recorder.prototype.hasOperate = function() {
		return this.updateRecords.size() + this.newRecords.size() + this.deleteRecords.size() > 0;
	};
}
/**
 * 打包提交到后台
 * @param structure:数组类型，需要打包的数据的结构
 * @author lj
 */
if (!Recorder.prototype.pack) {
	Recorder.prototype.pack = function(structure) {
		var that = this;
		var cleanup = function(arr,structure) {
		    if (!ArrayUtil.hasData(arr)) {
		        return [];
		    }
		    if (!structure) {
		    	return arr;
		    }
		    var mArr = [];
		    $.each(arr, function(index, item){
		        var mObj = {};
		        $.each(structure, function(sIndex, sItem){
		            mObj[sItem] = item[sItem];
		        });
		        mArr.push(mObj);
		    });
		    return mArr;
		};
		return {
			'newRecords': (function(){
				return cleanup(that.newRecords.arr,structure);
			})(), 
			'updateRecords': (function(){
				return cleanup(that.updateRecords.arr,structure);
			})(),
			'deleteRecords':(function(){
				return cleanup(that.deleteRecords.arr,structure);
			})()
		};
	};
}
/**
 * 触发点记录器
 */
if (!TriggerRecorder) {
    function TriggerRecorder(){
    	this.hasChangedState = false;
    }
}
/**
 * 切换触发器
 * @param id 触发器id
 */
if (!TriggerRecorder.prototype.switchTrigger) {
	TriggerRecorder.prototype.switchTrigger = function(id) {
		this.triggerId = id;
		this.hasChangedState = false; // 触发对象是否发生改变，默认为false
	};
}
/**
 * 判断触发器是否发生改变
 */
if (!TriggerRecorder.prototype.isSelfTrigger) {
	TriggerRecorder.prototype.isSelfTrigger = function(id) {
		return this.triggerId == id;
	};
}
if (!TriggerRecorder.prototype.hasChanged) {
	TriggerRecorder.prototype.hasChanged = function() {
		return this.hasChangedState;
	};
}
/**
 * 使hasChangedState发生变化
 */
if (!TriggerRecorder.prototype.doChange) {
	TriggerRecorder.prototype.doChange = function() {
		this.hasChangedState = true;
	};
}
if (!TriggerRecorder.prototype.getTriggerId) {
	TriggerRecorder.prototype.getTriggerId = function() {
		return this.triggerId;
	};
}
